package com.jin.webvideo.base.httpclient;


import org.apache.http.HttpHost;
import java.util.*;

public class HandlerProvider {
    private static final Object lock = new Object();

    // installed providers
    private static volatile List<HttpSurroundHandler> installedHandler;

    // used to avoid recursive loading of instaled providers
    private static boolean loadingHandler = false;

    /**
     *
     * @param host
     * @return
     */
    public static HttpSurroundHandler getHandler(HttpHost host) {
        for (HttpSurroundHandler handler : HandlerProvider.installedProviders()) {
            if (host.equals(handler.getHost())) {
                return handler;
            }
        }
        return null;
    }

    public static List<HttpSurroundHandler>  installedProviders() {
        if (installedHandler == null) {
            // 确保默认接口 已初始化
            synchronized (lock) {
                if (installedHandler == null) {
                    if (loadingHandler) {
                        throw new Error("Circular loading of installed handler detected");
                    }
                    loadingHandler = true;
                    List<HttpSurroundHandler> list = loadInstalledHandler();
                    // 插入默认的提供者
                    installedHandler = Collections.unmodifiableList(list);
                }
            }
        }
        return installedHandler;
    }

    private static List<HttpSurroundHandler> loadInstalledHandler() {
        List<HttpSurroundHandler> list = new ArrayList<>();
        ServiceLoader<HttpSurroundHandler> handlers = ServiceLoader.load(HttpSurroundHandler.class, HandlerProvider.class.getClassLoader());
        for (HttpSurroundHandler handler : handlers) {
            HttpHost host = handler.getHost();
            boolean found = false;
            for (HttpSurroundHandler h : list) {
                if (h.equals(host)) {
                    found = true;
                    break;
                }
            }
            if (!found) {
                list.add(handler);
            }
        }
        return list;
    }

}
